#include <OneWire.h> //include 1Wire Library
//Preliminary coding 28/6/2010 - 

int menucount         = 0 ; //display the first menu
int dispint         = 0 ; //initialise the display
int FridgePin         = 13; //Output Pin for the fridge
int IntTempPin         = 10; //Pin that the Internal Temp Sensor is connected to
int ExtTempPin        = 9; //Pin that the External Temp Sensor is connected to
int FriTempPin        = 10; //Pin that the Fridge Temp Sensor is connected to
int DesiredTemp        = 19; //Default Desired Fridge Temp
int sensorPin         = 0 ; //Analog potentiometer to set fridge tempreture
int buttonPin        = 2 ; //pin that the button is attached to 
int button2Pin        = 4 ; //pin that the button is attached to 
int temp1            = 0 ; //temperature holder1
int temp2            = 0 ; //temperature holder2
int temp3            = 99 ; //temperature holder3

int FriStatus         = 0 ; //Current fridge status- on or off

void setup() {
    Serial.begin(9600); //Setup Serial
    Serial.print(0xFE, BYTE);
    Serial.print(0x42, BYTE);   
    Serial.print(0xFE, BYTE);
    Serial.print(0x41, BYTE);
    Serial.print(0xFE, BYTE);
    Serial.print(0x48, BYTE);
    backlightOn();  //Turn on LCD and BackLight
    pinMode(buttonPin, OUTPUT);
    pinMode(button2Pin, INPUT);
    pinMode(FridgePin, OUTPUT); //Set the fridge-pin to output
    digitalWrite(FridgePin, LOW); // Ensure fridge is OFF to begin with
    clearLCD();
    delay(100);//Add a short delay after clearing
    Serial.print("Welcome");
    delay(1000);
    clearLCD();
            }
void loop() {

switch (menucount) { //Case Statement to print the LCD Screens
    case 1:
        DrawMenu1();
        break;
    case 2:
        DrawMenu2();
        break;
    case 3:
        menureset();
        break;
    case 4:
        DrawMenu4();
        break;    
    case 5:
        DrawMenu5();
        break;    
    default:
        menureset();
        break;        
                    }

fridgemgr(); //Call the fridge management module
attachInterrupt(0, menuinterrupt, RISING); //Sets the interrupt up                    
            }
void menuinterrupt() { //The interrupt procedure- Done
 if(digitalRead(button2Pin) == HIGH){
    if (menucount < 2) {
  menucount = menucount + 1;            // Add 1 to MenuCount
  } else {menucount = 1;}
  dispint = 0;                           // Flag Display to be re-drawn
  clearLCD();
  }
} 
void DrawMenu1() { // First Menu, containing temp and voltage
        temp1= ReadTemp(IntTempPin);
        temp2= analogRead(sensorPin); //ReadTemp(ExtTempPin);
        temp3= 99;
if (dispint < 2) {//initialise display for this menu
        clearLCD();
        delay(100);
        cursorHome();
        Serial.print("INT:");
        Serial.print(temp2);
        Serial.print("c");
        cursorSet(1,0);
        Serial.print("EXT:");
        Serial.print(temp1);
        Serial.print("c");
        dispint++; //set initialise flag to 0
                  } //leave loop and begin to print temp and voltage fields
    cursorSet(5,0);
    //backSpace(6);
    Serial.print(temp1); //print external temperature
    Serial.print("c");
    cursorSet(5,1);
    //backSpace(6);
    Serial.print(temp2); //print internal temperature
    Serial.print("c");
}
void DrawMenu2() { // Second Menu containing fridge details
temp3= ReadTemp(FriTempPin);
if (dispint < 5) {
        //clearLCD();    //initialise display for this menu
        cursorHome(); //Take Cursor to 1,1
        delay(100);
        Serial.print("FRIDGE:"); //Print Fridge label
        Serial.print(temp3); //print fridge temp
        Serial.print("c"); //print c lavel
        cursorSet(1,0);//goto second line
        if (FriStatus == 1){
            Serial.print("ON ");
                            } 
            else {Serial.print("OFF ");}
        Serial.print("TARGET:"); //print target temp label
        Serial.print(DesiredTemp); //print desired Temp
        Serial.print("c"); //print c label
        dispint = 0; //set initialise flag to 0
                  } 
    ////DesiredTemp = analogRead(sensorPin); //    Set the desired Temp using the pot        
    // cursorSet(0,14); //Delete Current temp and re-generate
    // backSpace(6);
    // Serial.print(temp1));
    // Serial.print("c");
    // cursorSet(1,0); //delete current status and re-generate
    ////backSpace(3);
    ////Serial.print(FriStatus);    
    // cursorSet(1,11);//delete desired temp and re-generate
    ////backSpace(2);
    // Serial.print(DesiredTemp);
    // Serial.print("c");
    
                  
}
void DrawMenu3() { // Third Menu containing average temp -not ready
if (dispint == 1) {
    //initialise display for this menu
    clearLCD();
    dispint = 0; //set initialise flag to 0
                  } 
}
void DrawMenu4() { // Forth Menu containing Detailed Temp - not ready
if (dispint == 1) {
    //initialise display for this menu
    dispint = 0; //set initialise flag to 0
    clearLCD();
                    } 
}
void DrawMenu5() { // Fifth Menu Containing Detailed Voltage - not ready
if (dispint == 1) {
        //initialise display for this menu
        dispint = 0; //set initialise flag to 0
        clearLCD();
            } 
}
void menureset() { //Resets the menu when max_count is reached
menucount = 1;
}
void fridgemgr() { //Manages the fridge thermostat- separate to menu - Done
if (temp3 == 99){
        temp3 = ReadTemp(FriTempPin);
        }
if ( temp3 > DesiredTemp) {
    digitalWrite(FridgePin, HIGH);
    FriStatus = 1;
                                        }
else                                    {
    digitalWrite(FridgePin, LOW);
    FriStatus = 0;
                                        }
                }                

//Temp Reading Functions                
int ReadTemp (int PinRead) { //Read Temp

OneWire  ds(PinRead);  // on pin x

  byte i;

  byte present = 0;

  byte data[12];

  byte addr[8];

  int Temp;

  if ( !ds.search(addr)) {

    //Serial.print("No more addresses.\n");

    ds.reset_search();

   // return;

  }

  //Serial.print("R=");  //R=28 Not sure what this is

  for( i = 0; i < 8; i++) {

    //Serial.print(addr[i], HEX);

    //Serial.print(" ");

  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {

    //Serial.print("CRC is not valid!\n");

   // return;

  }

  if ( addr[0] != 0x28) {

    //Serial.print("Device is not a DS18S20 family device.\n");

    //return;

  }

  ds.reset();

  ds.select(addr);

  ds.write(0x44,1);       // start conversion, with parasite power on at the end

 // delay(750);     // maybe 750ms is enough, maybe not

  // we might do a ds.depower() here, but the reset will take care of it.

  present = ds.reset();

  ds.select(addr);

  ds.write(0xBE);       // Read Scratchpad

  //Serial.print("P=");

  //Serial.print(present,HEX);

  //Serial.print(" ");

  for ( i = 0; i < 9; i++) {         // we need 9 bytes

    data[i] = ds.read();

    //Serial.print(data[i], HEX);

    //Serial.print("  ");

  }

  Temp=(data[1]<<8)+data[0];//take the two bytes from the response relating to temperature

  Temp=Temp>>4;//divide by 16 to get pure celcius readout

  //next line is Fahrenheit conversion

  //Temp=Temp*1.8+32; // comment this line out to get celcius

  //Serial.print("T=");//output the temperature to serial port

  //Serial.print(Temp);

    //Serial.print("  ");

  //Serial.print(" CRC=");

  //Serial.print( OneWire::crc8( data, 8), HEX);

  //Serial.println();
    return Temp;
} 


//LCD Functions
void clearLCD(){ // clear the LCD
  Serial.print(0xFE, BYTE);
  Serial.print(0x51, BYTE);
}

void cursorHome(){// move the cursor to the home position
  Serial.print(254, BYTE);
  Serial.print(70, BYTE);
}

void newLine(){ //Move to next line
  cursorSet(0,1);
}

void cursorSet(int xpos, int ypos){  // move the cursor to a specific place X Y
//e.g.: cursorSet(3,2) sets the cursor to x = 3 and y = 2
  Serial.print(254, BYTE);
  Serial.print(69, BYTE);               
  Serial.print(xpos,BYTE);   //Column position   
  Serial.print(ypos,BYTE); //Row position 
} 

void backSpace(int spaces) { // backspace and erase previous character
int x;
  for(x < (spaces+1); x++;){
                Serial.print(78, BYTE);
                Serial.print(8, BYTE); 
                            }
}

void cursorLeft(){    // move cursor left
  Serial.print(254, BYTE); 
  Serial.print(73, BYTE);   
}
 
void cursorRight(){ // move cursor right
  Serial.print(254, BYTE); 
  Serial.print(74, BYTE);   
}

void backlightOn(){ // turn on backlight
  Serial.print(0xFE, BYTE); 
  Serial.print(0x52, BYTE);      
}

void backlightOff(){ // turn off backlight
  Serial.print(0xFE, BYTE); 
  Serial.print(0x53, BYTE);   
}

//End LCD Functions 